@use 'sass:map';

@use './shared' as *;
@use './design' as *;

$checkbox: () !default;
$checkbox: map.merge(
  (
    label-color: inherit,
    label-color-checked: get-css-var('color-primary-base'),
    label-color-disabled: get-css-var('content-color-disabled'),
    b-color: get-css-var('border-color-base'),
    b-color-hover: get-css-var('color-primary-base'),
    b-color-checked: get-css-var('color-primary-base'),
    b-color-disabled: get-css-var('fill-color-disabled'),
    signal-bg-color: get-css-var('fill-color-base'),
    signal-bg-color-checked: get-css-var('color-primary-base'),
    signal-bg-color-disabled: get-css-var('fill-color-background'),
    signal-check-color: get-css-var('color-white'),
    radius: get-css-var('radius-base'),
    signal-radius: get-css-var('radius-small'),
    s-color-focus: get-css-var('color-primary-opacity-6'),
    signal-small-size: 14px,
    signal-small-thick: 1px,
    signal-size: 18px,
    signal-thick: 2px,
    signal-large-size: 22px,
    signal-large-thick: 3px,
    series-h-span: 10px,
    series-v-span: 6px
  ),
  $checkbox
);

.#{$namespace}-checkbox {
  &-vars {
    @include define-preset-values('checkbox', $checkbox);
  }

  @mixin define-checkbox-style($style-map) {
    @include define-preset-style('checkbox', $style-map);
  }

  @include basis;

  position: relative;
  display: inline-flex;
  align-items: center;
  line-height: 1;
  vertical-align: middle;
  cursor: pointer;
  user-select: none;
  transition: get-css-var('transition-background'), get-css-var('transition-border'),
    get-css-var('transition-shadow');

  &--border {
    padding: 8px 10px;
    border: get-css-var('border-shape') get-css-var('checkbox-b-color');
    border-radius: get-css-var('checkbox-radius');

    &:hover {
      border-color: get-css-var('checkbox-b-color-hover');
    }
  }

  &--checked#{&}--border {
    border-color: get-css-var('checkbox-b-color-checked');
  }

  &--loading {
    cursor: auto;
  }

  &__signal {
    position: relative;
    display: inline-block;
    width: get-css-var('checkbox-signal-size');
    height: get-css-var('checkbox-signal-size');
    background-color: get-css-var('checkbox-signal-bg-color');
    border: get-css-var('border-shape') get-css-var('checkbox-b-color');
    border-radius: get-css-var('checkbox-signal-radius');
    transition: get-css-var('transition-background'), get-css-var('transition-border'),
      get-css-var('transition-shadow');

    &::before {
      position: absolute;
      inset: -4px 25% auto;
      width: auto;
      height: 0;
      pointer-events: none;
      content: '';
      border-top: get-css-var('border-shape') get-css-var('checkbox-b-color');
      opacity: 0%;
    }

    &--active::before {
      opacity: 100%;
      animation: vxp-h-moving-border 1000ms infinite linear;
    }

    &::after {
      position: absolute;
      top: calc(50% - 1px);
      left: 50%;
      width: calc(
        get-css-var('checkbox-signal-size') * 0.25 + get-css-var('checkbox-signal-thick') * 0.5 -
          0.5px
      );
      height: calc(get-css-var('checkbox-signal-size') * 0.5);
      content: '';
      background-color: transparent;
      border: solid get-css-var('checkbox-signal-check-color');
      border-width: 0 get-css-var('checkbox-signal-thick') get-css-var('checkbox-signal-thick') 0;
      opacity: 0%;
      transition:
        width get-css-var('transition-base'),
        height get-css-var('transition-base'),
        get-css-var('transition-background'),
        get-css-var('transition-opacity'),
        get-css-var('transition-transform');
      transform: translate(-50%, -50%) rotate(45deg) scale(0);
    }
  }

  &:focus-within &__signal {
    box-shadow: get-css-var('shadow-focus') get-css-var('checkbox-s-color-focus');
  }

  @mixin small-signal {
    @include define-preset-values(
      'checkbox',
      (
        signal-size: 14px,
        signal-thick: 1px
      )
    );
  }

  @mixin large-signal {
    @include define-preset-values(
      'checkbox',
      (
        signal-size: 22px,
        signal-thick: 3px
      )
    );
  }

  &--small {
    @include small-signal;
  }

  &--large {
    @include large-signal;
  }

  &__label {
    margin-inline-start: 6px;
    color: get-css-var('checkbox-label-color');
    transition: get-css-var('transition-color');
  }

  &:hover &__signal {
    &,
    &::before {
      border-color: get-css-var('checkbox-b-color-hover');
    }
  }

  @mixin partial-signal {
    background-color: get-css-var('checkbox-signal-bg-color-checked');
    border-color: get-css-var('checkbox-b-color-checked');

    &::after {
      top: 50%;
      width: calc(get-css-var('checkbox-signal-size') * 0.5);
      height: 1px;
      opacity: 100%;
      transform: translate(-50%, -50%) scale(1);
    }
  }

  &--partial &__signal {
    @include partial-signal;
  }

  &--checked &__signal {
    background-color: get-css-var('checkbox-signal-bg-color-checked');

    &,
    &::before {
      border-color: get-css-var('checkbox-b-color-checked');
    }

    &::after {
      opacity: 100%;
      transform: translate(-50%, -50%) rotate(45deg) scale(1);
    }
  }

  &--checked &__label {
    color: get-css-var('checkbox-label-color-checked');
  }

  $states: success, error, warning;

  @each $state in $states {
    &--#{$state} {
      @include define-checkbox-style(
        (
          label-color-checked: 'color' $state 'base',
          b-color: 'color' $state 'base',
          b-color-hover: 'color' $state 'base',
          b-color-checked: 'color' $state 'base',
          signal-bg-color-checked: 'color' $state 'base',
          s-color-focus: 'color' $state 'opacity-6'
        )
      );
    }
  }

  &--disabled,
  &--disabled#{&}--border {
    cursor: not-allowed;

    &,
    &:hover {
      border-color: get-css-var('checkbox-b-color-disabled');
    }
  }

  &--disabled &__signal,
  &--disabled:hover &__signal {
    background-color: get-css-var('checkbox-signal-bg-color-disabled');

    &,
    &::before {
      border-color: get-css-var('checkbox-b-color-disabled');
    }

    &::after {
      border-color: get-css-var('checkbox-b-color-disabled');
    }
  }

  &--disabled &__label {
    color: get-css-var('checkbox-label-color-disabled');
  }

  &--disabled#{&}--checked &__signal {
    background-color: get-css-var('checkbox-signal-bg-color-disabled');
  }

  &__input {
    width: 0;
    height: 0;
    margin: 0;
    pointer-events: none;
    opacity: 0%;
  }

  @at-root {
    &-group {
      @include basis;

      display: inline-flex;
      align-items: center;
      justify-content: flex-start;

      &--vertical {
        flex-direction: column;
        align-items: flex-start;
        justify-content: center;
      }
    }

    &-group & {
      margin-inline-end: get-css-var('checkbox-series-h-span');
    }

    &-group--vertical & {
      margin-inline-end: 0;
      margin-bottom: get-css-var('checkbox-series-v-span');

      &:last-child {
        margin-bottom: 0;
      }
    }

    &-group--border & {
      padding: 8px 10px;
      border: get-css-var('border-shape') get-css-var('checkbox-b-color');
      border-radius: get-css-var('checkbox-radius');

      &:hover {
        border-color: get-css-var('checkbox-b-color-hover');
      }

      &--checked {
        border-color: get-css-var('checkbox-b-color-checked');
      }
    }

    &-group--border &--disabled {
      &,
      &:hover {
        border-color: get-css-var('checkbox-b-color-disabled');
      }
    }

    &-group--disabled & {
      cursor: not-allowed;

      &,
      &:hover {
        border-color: get-css-var('checkbox-b-color-disabled');
      }

      &__signal {
        border-color: get-css-var('checkbox-b-color-disabled') !important;

        &::after {
          background-color: get-css-var('checkbox-b-color-disabled');
        }
      }

      &__label {
        color: get-css-var('checkbox-label-color-disabled');
      }
    }

    &-group--disabled &--checked &__signal {
      background-color: get-css-var('checkbox-b-color-disabled');
    }

    &-group--small & {
      @include small-signal;
    }

    &-group--large & {
      @include large-signal;
    }
  }
}
